﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Configuration;
using System.IO;
using System.Text.RegularExpressions;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Collections;
using System.Reflection;

namespace ProcessAnalysis
{
    public enum Performances
    {
        Cpu_Consumption_Comparison,
        Private_Memory_Use,
        Paging_Space,
        Number_Of_Thread,
        Virtual_Memory_Size,
        Phisical_Memory,
        Modules_Loaded,
        Traffic_Received,
        Traffic_Sent,
        Compression_Ratio,
        DeCompression_Ratio
    }

    public enum ConfigurationsNames
    {
        programPath,
        CloseAfterRun,
        ExistingProgram,
        WaitForExit,
        ProcessesRunningTime
    }

    public partial class ProcessAnalysis : Form
    {
        #region Private fields

        private double[][][] performancesArray;

        public String[] performancesNames;

        private bool isSaved;

        private bool stopOneFlag;

        private bool stopAllFlag;

        private int runningTime;

        private string currentFilePath;

        private RunningOptionsProperties runningOptions = new RunningOptionsProperties();

        private SvgGraphs PerformancesGraphs;

        private RunningParameters runningParameters;

        public static string resultsForPPA = string.Empty;
           
        #endregion

        public ProcessAnalysis()
        {
            isSaved = true;
            InitializeComponent();
            performancesNames = typeof(Performances).GetEnumNames();
            currentFilePath = string.Empty;

            foreach (DataGridViewColumn column in ApplicationsGridView.Columns)
            {
                column.SortMode = DataGridViewColumnSortMode.NotSortable;
            }
        }

        #region Private Methods

        private void Save()
        {
            if (String.IsNullOrEmpty(currentFilePath))
            {
                DialogResult userClickedOK = SaveFileDialog.ShowDialog();
                if (userClickedOK == System.Windows.Forms.DialogResult.OK)
                {
                    currentFilePath = SaveFileDialog.FileName;
                }
            }
            if (!string.IsNullOrEmpty(currentFilePath))
            {
                WriteToSavedFile(currentFilePath);
            }
            isSaved = true;
            this.Text = GetWindowName();
        }

        private void WriteToSavedFile(string fullFilePath)
        {
            string fileContain = string.Empty;
            foreach (DataGridViewRow row in ApplicationsGridView.Rows)
            {
                fileContain += 
                    string.Format("{0}{1}*{2}*{3}{4}*{5}*{6}{7}*{8}*{9}{10}*{11}*", 
                    ConfigurationsNames.programPath.ToString(), row.Index + 1,row.Cells[1].Value, 
                    ConfigurationsNames.CloseAfterRun.ToString(), row.Index + 1, row.Cells[2].Value,
                    ConfigurationsNames.ExistingProgram.ToString(), row.Index + 1, row.Cells[3].Value,
                    ConfigurationsNames.WaitForExit.ToString(), row.Index + 1, row.Cells[4].Value);
            }

            String[] performancesNames = typeof(Performances).GetEnumNames();
 
           
            for (int i = 0; i < typeof(Performances).GetEnumNames().Length; i++)
            {
                for (int j = 0; j < ApplicationsGridView.Rows.Count; j++)
                {
                    try
                    {
                        fileContain += string.Format("{0}{1}*{2}*", performancesNames[i], j+1, performancesArray[i][j].Join(','));
                    }
                    catch
                    {
                        fileContain += string.Format("{0}{1}**", performancesNames[i], j+1);
                    }
                }
            }

            fileContain +=
                string.Format("{0}*{1}*", ConfigurationsNames.ProcessesRunningTime.ToString(), runningOptions.ProcessesRunningTime);

            foreach (PropertyInfo property in typeof(RunningOptionsProperties).GetProperties())
            {
                if (!property.Name.Equals(ConfigurationsNames.ProcessesRunningTime.ToString()))
                {
                    fileContain += string.Format("Graph{0}*{1}*", property.Name, (bool)property.GetValue(runningOptions, null));
                }
            }
                
            File.WriteAllText(fullFilePath, fileContain);
        }

        private string GetNameFromPath(string path)
        {
            string[] programPathArray = path.Split(new[] { '\\' });
            return programPathArray[programPathArray.Length - 1];
        }

        private void LoadDataFromFile(string saveFilePath)
        {
            try
            {
                string fileContain = File.ReadAllText(saveFilePath);
                List<string> pathsList = new List<string>();
                List<string> closeAfterRunList = new List<string>();
                List<string> existingProgramList = new List<string>();
                List<string> waitForExitList = new List<string>();

                var matches = Regex.Matches(fileContain, ConfigurationsNames.programPath + "([0-9]*)");
                foreach(Match match in matches)
                {
                    if (match.Success)
                    {
                        pathsList.Add(GetValue(fileContain, match.ToString()));
                    }
                }
                matches = Regex.Matches(fileContain, ConfigurationsNames.CloseAfterRun + "([0-9]*)");
                foreach (Match match in matches)
                {
                    if (match.Success)
                    {
                        string currValue = GetValue(fileContain, match.ToString());
                        if (string.IsNullOrEmpty(currValue))
                        {
                            currValue = "False";
                        }

                        closeAfterRunList.Add(currValue);
                    }
                }
                matches = Regex.Matches(fileContain, ConfigurationsNames.ExistingProgram + "([0-9]*)");
                foreach (Match match in matches)
                {
                    if (match.Success)
                    {
                        string currValue = GetValue(fileContain, match.ToString());
                        if (string.IsNullOrEmpty(currValue))
                        {
                            currValue = "True";
                        }

                        existingProgramList.Add(currValue);
                    }
                }

                matches = Regex.Matches(fileContain, ConfigurationsNames.WaitForExit + "([0-9]*)");
                foreach (Match match in matches)
                {
                    if (match.Success)
                    {
                        string currValue = GetValue(fileContain, match.ToString());
                        if (string.IsNullOrEmpty(currValue))
                        {
                            currValue = "True";
                        }

                        waitForExitList.Add(currValue);
                    }
                }

                for (int i = 0; i < pathsList.Count; i++)
                {
                    ApplicationsGridView.Rows.Add(new[] { 
                        GetNameFromPath(pathsList[i]), pathsList[i],closeAfterRunList[i],existingProgramList[i],waitForExitList[i]});
                }

                runningOptions.ProcessesRunningTime = 
                    Int32.Parse(GetValue(fileContain, ConfigurationsNames.ProcessesRunningTime.ToString()));

                foreach (PropertyInfo property in typeof(RunningOptionsProperties).GetProperties())
                {
                    if (!property.Name.Equals(ConfigurationsNames.ProcessesRunningTime.ToString()))
                    {
                        property.SetValue(runningOptions, 
                            Boolean.Parse(GetValue(fileContain, string.Format("Graph{0}", property.Name))), null);
                    }
                }

                performancesArray = new double[performancesNames.Length][][];
                for (int i = 0; i < typeof(Performances).GetEnumNames().Length; i++)
                {
                    performancesArray[i] = new double[ApplicationsGridView.Rows.Count][];
                    for (int j = 0; j < ApplicationsGridView.Rows.Count; j++)
                    {
                        string[] stringArray = 
                            GetValue(fileContain, string.Format("{0}{1}",performancesNames[i],j+1)).Split(new[] { ',' });

                        if (string.IsNullOrEmpty(stringArray[0]))
                        {
                            performancesArray[i][j] = null;
                        }
                        else
                        {
                            performancesArray[i][j] = Array.ConvertAll(stringArray, new Converter<string, double>(double.Parse));
                        }
                    }
                }

                currentFilePath = saveFilePath;
                this.Text = GetWindowName();
            }
            catch (Exception exp)
            {
                MessageBox.Show("Bad file!\n" + exp.Message);
            }
        }

        private int[] GetSelectedRowsIndexes()
        {
            List<int> result = new List<int>();
           
            foreach (DataGridViewRow row in ApplicationsGridView.SelectedRows)
            {
                result.Add(row.Index);
            }

            foreach (DataGridViewCell cell in ApplicationsGridView.SelectedCells)
            {
                result.Add(cell.RowIndex);
            }

            result.Sort();
            return result.Distinct<int>().ToArray<int>(); ;
        }

        private DataGridViewRow[] GetSelectedRows()
        {
            int[] rowIndexes = GetSelectedRowsIndexes();
            List<DataGridViewRow> result = new List<DataGridViewRow>();

            foreach (int index in rowIndexes)
            {
                result.Add(ApplicationsGridView.Rows[index]);
            }

            return result.ToArray();
        }

        private string GetValue(string fileContain, string optionName)
        {
            string[] fileContainArray = fileContain.Split(new[] {'*'});
            for (int i = 0; i < fileContainArray.Length; i+=2)
            {
                if (fileContainArray[i] == optionName)
                {
                    return fileContainArray[i + 1];
                }
            }
            return null;
        }

        private string GetWindowName()
        {
            string windowName = "Process Analysis";
            if (!String.IsNullOrEmpty(currentFilePath))
            {
                windowName += " - " + currentFilePath;
            }
            return windowName;
        }

        private bool CheckIfSavedAndClear()
        {
            if (!isSaved)
            {
                DialogResult res = MessageBox.Show("Do you want to save changes?", "Process Analysis", MessageBoxButtons.YesNoCancel);
                if (res == DialogResult.Yes)
                {
                    Save();
                }
                else if (res == System.Windows.Forms.DialogResult.Cancel)
                {
                    return false;
                }
            }

            isSaved = true;
            ApplicationsGridView.Rows.Clear();
            performancesArray = null;
            runningOptions = new RunningOptionsProperties();
            currentFilePath = string.Empty;
            this.Text = GetWindowName();

            return true;
        }
        
        #endregion

        #region Events

        private void LoadToolStripMenuItemClick(object sender, EventArgs e)
        {
            if (CheckIfSavedAndClear())
            {
                // Call the ShowDialog method to show the dialog box.
                DialogResult userClickedOK = OpenFileDialog.ShowDialog();

                // Process input if the user clicked OK.
                if (userClickedOK == System.Windows.Forms.DialogResult.OK)
                {
                    string saveFilePath = OpenFileDialog.FileName;
                    LoadDataFromFile(saveFilePath);
                }
            }
        }

        private void ExitToolStripMenuItemClick(object sender, EventArgs e)
        {
            Close();
        }

        private void LoadProgramBtnClick(object sender, EventArgs e)
        {
            // Call the ShowDialog method to show the dialog box.
            DialogResult userClickedOK = OpenAllFilesDialog.ShowDialog();

            // Process input if the user clicked OK.
            if (userClickedOK == System.Windows.Forms.DialogResult.OK)
            {
                String programPath = OpenAllFilesDialog.FileName;
                if (!string.IsNullOrEmpty(programPath))
                {
                    AddProgram(programPath);
                    isSaved = false;
                }
            }
        }

        public void AddProgram(string programPath)
        {
            ApplicationsGridView.Rows.Add(new[] { GetNameFromPath(programPath), programPath, "False", "True", "False" });
        }

        public void RunBtnClick(object sender, EventArgs e)
        {
            int numSelectedRows = GetSelectedRowsIndexes().Length;

            if (numSelectedRows == 0)
            {
                MessageBox.Show("Select rows!");
                return;
            }

            //prepare to ticks
            RunningProgramParameters[] runningProgramsParameters = new RunningProgramParameters[numSelectedRows];
            runningParameters = new RunningParameters(runningProgramsParameters);
            runningParameters.currentRunningProgram = 0;
            AnalaysisProgressBar.Value = 0;
            runningTime = 0;
            AnalaysisProgressBar.Maximum = runningOptions.ProcessesRunningTime * 1000 * runningProgramsParameters.Length + 100;
            ApplicationsGridView.Enabled = false;
            ChooseProgramBtn.Enabled = false;
            RunBtn.Enabled = false;
            ShowResultsBtn.Enabled = false;
            fileToolStripMenuItem.Enabled = false;
            optionsToolStripMenuItem.Enabled = false;
            ProgressBarTimer.Enabled = true;
            BtnStopAll.Visible = true;
            BtnStopOne.Visible = true;
            stopOneFlag = false;
            stopAllFlag = false;
            RunningProgramText.Text = "";
            RunningProgramText.Visible = true;
            TopMost = true;
        }

        public void SelectRow(int rowNumber)
        {
            ApplicationsGridView.Rows[rowNumber].Selected = true;
        }

        private void ProgressBarTimerTick(object sender, EventArgs e)
        {
            DataGridViewRow[] rows = GetSelectedRows();

            try
            {
                ProgressBarTimer.Enabled = false;
                int[] selectedRowIndexes = GetSelectedRowsIndexes();
                int programIndex = runningParameters.currentRunningProgram;
                int programRowIndex = selectedRowIndexes[programIndex];
                
                //first new process
                if ((runningTime % (runningOptions.ProcessesRunningTime * 1000) == 0 &&
                      rows[programIndex].Cells[4].Value.ToString() == "False") || stopOneFlag || stopAllFlag || runningTime == 0)
                {
                    if (stopOneFlag)
                    {
                        AnalaysisProgressBar.Value = (int)((AnalaysisProgressBar.Maximum * (programIndex + 1)) / rows.Length);
                        AnalaysisProgressBar.Value -= (int)(AnalaysisProgressBar.Value % 100);
                        runningTime = AnalaysisProgressBar.Value;
                    }

                    stopOneFlag = false;

                    if (runningTime > 0 || stopOneFlag || stopAllFlag)
                    {
                        if ((rows[programIndex].Cells[2].Value.ToString() == "True") &&
                            !runningParameters.runningProgramParameters[programIndex].process.HasExited)
                        {
                            runningParameters.runningProgramParameters[programIndex].process.Kill();
                        }

                        programIndex++;
                        runningParameters.currentRunningProgram++;

                        //end of measurements
                        if (programIndex >= runningParameters.runningProgramParameters.Length || stopAllFlag)
                        {
                            #region for PAA

                            string Path = rows[programIndex - 1].Cells[1].Value.ToString();
                            resultsForPPA += "**" + Path;
  
                            for (int i = 0; i < performancesNames.Length; i++)
                            {
                                resultsForPPA += "*" + performancesNames[i];

                                for (int j = 0; j < runningOptions.ProcessesRunningTime; j++)
                                {
                                    resultsForPPA += "," + performancesArray[i][0][j];
                                }
                            }

                            #endregion

                            runningParameters.currentRunningProgram = 0;
                            AnalaysisProgressBar.Value = 0;
                            runningTime = 0;
                            BtnStopAll.Visible = false;
                            BtnStopOne.Visible = false;
                            RunningProgramText.Text = "";
                            RunningProgramText.Visible = false;
                            ApplicationsGridView.Enabled = true;
                            ChooseProgramBtn.Enabled = true;
                            RunBtn.Enabled = true;
                            ShowResultsBtn.Enabled = true;
                            fileToolStripMenuItem.Enabled = true;
                            optionsToolStripMenuItem.Enabled = true;
                            ProgressBarTimer.Enabled = false;
                            isSaved = false;
                            this.TopMost = false;
                            return;
                        }

                        programIndex = runningParameters.currentRunningProgram;
                        programRowIndex = selectedRowIndexes[programIndex];
                    }

                    RunningProgramText.Text = "Running: " + rows[programIndex].Cells[0].Value.ToString();
                    String programPath = rows[programIndex].Cells[1].Value.ToString();
                    Process process = null;

                    string[] programPathArray = GetNameFromPath(programPath).Split(new[] { '.' });
                    string[] programNameArray = programPathArray.SubArray(0, programPathArray.Length - 1);
                    string programName = String.Join(".", programNameArray);
                    var processArray = System.Diagnostics.Process.GetProcessesByName(programName);

                    if (rows[programIndex].Cells[3].Value.ToString() == "True")
                    {
                        if (processArray.Length == 0)
                        {
                            stopOneFlag = true;
                            TopMost = false;
                            MessageBox.Show("The program " + programName + " doesn't exist!");
                            TopMost = true;
                            return;
                        }

                        process = processArray[0];
                    }
                    else
                    {
                        process = System.Diagnostics.Process.Start(programPath);
                    }

                    for (int i = 0; i < performancesNames.Length; i++)
                    {
                        performancesArray[i][programRowIndex] = new double[runningOptions.ProcessesRunningTime];
                    }

                    #region Cpu

                    PerformanceCounter totalCpu = new PerformanceCounter("Process", "% Processor Time", "_Total");
                    PerformanceCounter processCpu = new PerformanceCounter("Process", "% Processor Time", process.ProcessName);

                    double currentTotalCpu = totalCpu.NextValue();
                    double currentAppCpu = processCpu.NextValue();

                    #endregion

                    #region Network Received \ Sent

                    PerformanceCounterCategory performanceCounterCategory = new PerformanceCounterCategory("Network Interface");
                    PerformanceCounter performanceCounterSent =
                        new PerformanceCounter("Process", "IO Write Bytes/sec", process.ProcessName);
                    PerformanceCounter
                        performanceCounterReceived = new PerformanceCounter("Process", "IO Read Bytes/sec", process.ProcessName);

                    #endregion

                    runningParameters.runningProgramParameters[programIndex] =
                        new RunningProgramParameters(process, totalCpu, processCpu, performanceCounterReceived, performanceCounterSent);
                }

                int currentTick = runningParameters.runningProgramParameters[programIndex].currentTick;

                if (runningParameters.runningProgramParameters[programIndex].process.HasExited)
                {
                    stopOneFlag = true;
                }
                else if (runningTime % 1000 == 0) //every second do measurement
                {
                    if (currentTick >= performancesArray[0][programRowIndex].Length)
                    {
                        int arrayLength = performancesArray[0][programRowIndex].Length;
                        for (int i = 0; i < performancesNames.Length; i++)
                        {
                            List<double> tempList = new List<double>(performancesArray[i][programRowIndex]);
                            tempList.AddRange(new double[arrayLength]);
                            performancesArray[i][programRowIndex] = tempList.ToArray();
                        }           
                    }

                    #region Cpu

                    double currentTotalCpu = runningParameters.runningProgramParameters[programIndex].totalCpu.NextValue();
                    double currentAppCpu = runningParameters.runningProgramParameters[programIndex].processCpu.NextValue();

                    double newValue = (currentAppCpu / currentTotalCpu) * 100;
                    if (double.IsNaN(newValue) || double.IsInfinity(newValue))
                    {
                        newValue = 0;
                    }
                    performancesArray[(int)Performances.Cpu_Consumption_Comparison][programRowIndex][currentTick] = newValue;

                    #endregion

                    #region Private Memory Use

                    runningParameters.runningProgramParameters[programIndex].process.Refresh();
                    performancesArray[(int)Performances.Private_Memory_Use][programRowIndex][currentTick] =
                        runningParameters.runningProgramParameters[programIndex].process.PrivateMemorySize64;


                    #endregion

                    #region Paging Space

                    runningParameters.runningProgramParameters[programIndex].process.Refresh();
                    performancesArray[(int)Performances.Paging_Space][programRowIndex][currentTick] =
                        runningParameters.runningProgramParameters[programIndex].process.PagedMemorySize64;

                    #endregion

                    #region Number Of Threads

                    runningParameters.runningProgramParameters[programIndex].process.Refresh();
                    performancesArray[(int)Performances.Number_Of_Thread][programRowIndex][currentTick] =
                        runningParameters.runningProgramParameters[programIndex].process.Threads.Count;

                    #endregion

                    #region Virtual Memory

                    runningParameters.runningProgramParameters[programIndex].process.Refresh();
                    performancesArray[(int)Performances.Virtual_Memory_Size][programRowIndex][currentTick] =
                        runningParameters.runningProgramParameters[programIndex].process.VirtualMemorySize64;

                    #endregion

                    #region Phisical Memory

                    runningParameters.runningProgramParameters[programIndex].process.Refresh();
                    performancesArray[(int)Performances.Phisical_Memory][programRowIndex][currentTick] =
                        runningParameters.runningProgramParameters[programIndex].process.WorkingSet64;

                    #endregion

                    #region Modules Loaded

                    runningParameters.runningProgramParameters[programIndex].process.Refresh();
                    performancesArray[(int)Performances.Modules_Loaded][programRowIndex][currentTick] =
                        runningParameters.runningProgramParameters[programIndex].process.Modules.Count;

                    #endregion

                    #region Network Received

                    performancesArray[(int)Performances.Traffic_Received][programRowIndex][currentTick] =
                        runningParameters.runningProgramParameters[programIndex].performanceCounterReceived.NextValue();

                    #endregion

                    #region Network Sent

                    performancesArray[(int)Performances.Traffic_Sent][programRowIndex][currentTick] =
                        runningParameters.runningProgramParameters[programIndex].performanceCounterSent.NextValue();

                    #endregion

                    #region Compression Ratio

                    //compression ratio = compressed size / uncompressed size
                    double ratio = 0;
                    if (performancesArray[(int)Performances.Traffic_Received][programRowIndex][currentTick] != 0)
                    {
                        ratio = performancesArray[(int)Performances.Traffic_Sent][programRowIndex][currentTick] /
                                performancesArray[(int)Performances.Traffic_Received][programRowIndex][currentTick];
                        if (ratio > 1 || ratio < 0)
                        {
                            ratio = 0;
                        }
                    }
                    performancesArray[(int)Performances.Compression_Ratio][programRowIndex][currentTick] = ratio * 100;

                    #endregion

                    #region DeCompression Ratio

                    //de compression ratio = compressed size / uncompressed size
                    ratio = 0;
                    if (performancesArray[(int)Performances.Traffic_Received][programRowIndex][currentTick] != 0)
                    {
                        ratio = performancesArray[(int)Performances.Traffic_Received][programRowIndex][currentTick] /
                                performancesArray[(int)Performances.Traffic_Sent][programRowIndex][currentTick];
                        if (ratio > 1 || ratio < 0)
                        {
                            ratio = 0;
                        }
                    }
                    performancesArray[(int)Performances.DeCompression_Ratio][programRowIndex][currentTick] = ratio * 100;

                    #endregion

                    runningParameters.runningProgramParameters[programIndex].currentTick++;
                }

                if (rows[programIndex].Cells[4].Value.ToString() == "False")
                {
                    AnalaysisProgressBar.Value += 100;
                    runningTime = AnalaysisProgressBar.Value;
                }
                else
                {
                    runningTime += 100;
                }
                ProgressBarTimer.Enabled = true;
            }
            catch (Exception exc)
            {
                runningParameters.currentRunningProgram = 0;
                AnalaysisProgressBar.Value = 0;
                ApplicationsGridView.Enabled = true;
                ChooseProgramBtn.Enabled = true;
                RunBtn.Enabled = true;
                ShowResultsBtn.Enabled = true;
                fileToolStripMenuItem.Enabled = true;
                optionsToolStripMenuItem.Enabled = true;
                ProgressBarTimer.Enabled = false;
                BtnStopAll.Visible = false;
                BtnStopOne.Visible = false;
                RunningProgramText.Text = "";
                RunningProgramText.Visible = false;
                TopMost = false;
                MessageBox.Show("Test failed!\nMaybe the running program already exist\n(VS error: " + exc.Message + ")");
                return;
            }
        }

        private void SaveToolStripMenuItemClick(object sender, EventArgs e)
        {
            Save();
        }

        private void ShowResultsBtnClick(object sender, EventArgs e)
        {
            if (GetSelectedRowsIndexes().Length == 0)
            {
                MessageBox.Show("Select rows!");
                return;
            }

            if (!runningOptions.IsSomeGraphChoosen())
            {
                MessageBox.Show("Choose some graph!");
                return;
            }

            PerformancesGraphs = new SvgGraphs(GetSelectedRows(), performancesArray, runningOptions);
            PerformancesGraphs.ShowGraphs();
        }

        private void NewToolStripMenuItemClick(object sender, EventArgs e)
        {
            CheckIfSavedAndClear();
        }

        private void ProcessAnalysisFormClosing(object sender, FormClosingEventArgs e)
        {
            if (!isSaved)
            {
                DialogResult res = MessageBox.Show("Do you want to save changes?", "Process Analysis", MessageBoxButtons.YesNoCancel);
                if (res == DialogResult.Yes)
                {
                    Save();
                }
                else if (res == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
            if (PerformancesGraphs != null)
            {
                PerformancesGraphs.Delete();
            }
        }

        private void ProcessAnalysisKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.S)
            {
                Save();
            }
        }

        private void RunningOptionsToolStripMenuItemClick(object sender, EventArgs e)
        {
            RunningOptionsTool options = new RunningOptionsTool(runningOptions);
            options.ShowDialog();
            if (options.saveFlag)
            {
                isSaved = false;
            }
        }

        public void SetProcessesRunningTime(int seconds)
        {
            runningOptions.ProcessesRunningTime = seconds;
        }

        private void ApplicationsGridViewUserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            for (int i = 0; i < performancesNames.Length; i++)
            {
                performancesArray[i] = performancesArray[i].Where((el, k) => k != e.Row.Index).ToArray();
            }
            isSaved = false;
        }

        private void ApplicationsGridViewRowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            if (performancesArray == null)
            {
                performancesArray = new double[performancesNames.Length][][];
                for (int i = 0; i < performancesNames.Length; i++)
                {
                    performancesArray[i] = new double[1][];
                }
            }
            else
            {
                for (int i = 0; i < performancesNames.Length; i++)
                {
                    ArrayList newArray = new ArrayList(performancesArray[i]);
                    newArray.Add(null);
                    double[][] newRow = new double[newArray.Count][];
                    for (int k = 0; k < newArray.Count; k++)
                    {
                        newRow[k] = (double[])newArray[k];
                    }

                    performancesArray[i] = newRow;
                }
            }
        }

        private void BtnStopAllClick(object sender, EventArgs e)
        {
            stopAllFlag = true;
        }

        private void BtnStopOneClick(object sender, EventArgs e)
        {
            stopOneFlag = true;
        }

        #endregion
    }


    public class RunningParameters
    {
        public RunningProgramParameters[] runningProgramParameters;

        public int currentRunningProgram;
        
        public RunningParameters(RunningProgramParameters[] runningProgramParameters)
        {
            this.runningProgramParameters = runningProgramParameters;
        }
    }

    public class RunningProgramParameters
    {
        public Process process;
        public PerformanceCounter totalCpu;
        public PerformanceCounter processCpu;
        public PerformanceCounter performanceCounterReceived;
        public PerformanceCounter performanceCounterSent;

        public int currentTick;

        public RunningProgramParameters(Process process, PerformanceCounter totalCpu, PerformanceCounter processCpu,
            PerformanceCounter performanceCounterReceived, PerformanceCounter performanceCounterSent)
        {
            this.process = process;
            this.totalCpu = totalCpu;
            this.processCpu = processCpu;
            this.performanceCounterReceived = performanceCounterReceived;
            this.performanceCounterSent = performanceCounterSent;

            this.currentTick = 0;
        }
    }
}
